#ifndef ROBOTCOMMAND_H
#define ROBOTCOMMAND_H

#include "command.h"
#include "robot.h"
#include "global.h"


/************************************************************/
/*                  ROBOT COMMAND INTERFACE                 */
/************************************************************/
/**
 * @brief Defines the interface for a command that manipulates a robot.
 * Inherits Command.
 *
*/
class RobotCommand : public Command{
protected:
    /**
     * @brief The Robot object that receives this command.
     *
     */
    Robot* _robot;

public:
    /**
     * @brief Constructor.  Creates a new robot command.  The command needs
     * to know what Robot object it is affecting.
     *
     * @param robot The Robot this command affects.
     */
    RobotCommand(Robot* robot){_robot = robot;}

    virtual void execute() = 0;
    virtual void undo() = 0;
};


/************************************************************/
/*                ROBOT COMMAND GROUP CLASS                 */
/************************************************************/
/**
 * @brief Used to group several robot commands together.  Inherits RobotCommand
 *
 * The robot command group is used to perform several commands
 * on the robot in "batch mode".  See robot.h for more info
 * about modifying the robot in batch mode.
 *
*/
class RobotCommandGroup : public RobotCommand
{
private:
    QList<RobotCommand*> _commandList;

public:
    RobotCommandGroup(Robot* robot);

    void execute();
    void undo();

    void append(RobotCommand* command);
};


/************************************************************/
/*              MOVE ROBOT JOINT COMMAND CLASS              */
/************************************************************/
/**
 * @brief Moves a robot joint by a given angle amount.  Inherits RobotCommand
 *
*/
class MoveRobotJointCommand : public RobotCommand
{
private:
    int _jointID;
    float _delta;
    float _prevState;

public:
    MoveRobotJointCommand(Robot* robot, int jointID, float delta);

    void execute();
    void undo();
};


/************************************************************/
/*              SET ROBOT JOINT COMMAND CLASS               */
/************************************************************/
/**
 * @brief Moves a robot joint to a given angle.  Inherits RobotCommand
 *
*/
class SetRobotJointCommand : public RobotCommand
{
private:
    int _jointID;
    float _theta;
    float _prevState;

public:
    SetRobotJointCommand(Robot* robot, int jointID, float theta);

    void execute();
    void undo();
};



#endif // ROBOTCOMMAND_H
